// 方法装饰器：可以装饰方法
// (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => PropertyDescriptor | void

/**
 * @description:
 * @param {*} target  如果装饰实类的静态方法，target指向类本身，如果装饰类的实例方法，target指向类的原型对象
 * @param {*} propertyKey 装饰的成员名称
 * @param {*} descriptor 成员的属性描述
 * @return {*}
 */
function log(target, propertyKey, descriptor) {
  // 获取老的函数
  const originalMethod = descriptor.value
  // 重写原型上的属性
  descriptor.value = function (...args) {
    console.log(`Calling ${propertyKey} with`, args)
    const result = originalMethod.apply(this, args)
    console.log(`Called ${propertyKey} with`, args, 'and got', result)
    return result
  }
}

class Calculator {
  @log
  add(a: number, b: number) {
    return a + b
  }
}

const calculator = new Calculator()
calculator.add(2, 3)
